﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

using boda.net.wpf.core.Ioc;

using Prism.Ioc;

namespace boda.net.wpf.core.Extensions;
/// <summary>
/// 依赖注入扩展类，可以加载模块时。注入标注ExposedServiceAttribute特性的类
/// </summary>
public static class DependencyExtension
{
    private static List<Type> GetCustomeTypes(this Assembly assembly)
    {
        var result = assembly.GetTypes().Where(m =>
                m != null &&
                m.IsClass &&
                !m.IsAbstract &&
                m.CustomAttributes.Any(p => p.AttributeType == typeof(ExposedServiceAttribute)));
        return result.ToList();
    }

    /// <summary>
    /// 注册程序集
    /// </summary>
    /// <param name="container"></param>
    /// <param name="assembly"></param>
    public static void RegisterAssembly(this IContainerRegistry container, Assembly assembly)
    {
        var list = assembly.GetCustomeTypes();
        foreach (var type in list)
        {
            RegisterAssembly(container, type);
        }
    }

    private static IEnumerable<ExposedServiceAttribute> GetExposedServicee(this Type type)
    {
        var typeInfo = type.GetTypeInfo();
        return typeInfo.GetCustomAttributes<ExposedServiceAttribute>();
    }

    public static void RegisterAssembly(this IContainerRegistry container, Type type)
    {
        var list = type.GetExposedServicee();
        foreach (var item in list)
        {
            if (item.LifeTime == LifeTime.Singleton)
            {
                container.RegisterSingleton(type); // 注册单例
            }

            foreach (var IType in item.Types)
            {
                if (item.LifeTime == LifeTime.Singleton)
                {
                    container.RegisterSingleton(IType, type);  // 以接口注册单例
                }
                else if (item.LifeTime == LifeTime.Transient)
                {
                    container.Register(IType, type);  // 以接口注册瞬态
                }
            }
        }
    }

    /// <summary>
    /// 初始化注入标注ExposedServiceAttribute特性的类, 要求单例具自动加载AutoInitialize=true
    /// </summary>
    /// <param name="provider"></param>
    /// <param name="type"></param>
    public static void InitialAssembly(this IContainerProvider provider, Assembly assembly)
    {
        var list = assembly.GetCustomeTypes();

        foreach (var item in list)
        {
            InitialAssembly(provider, item);
        }
    }
    public static void InitialAssembly(IContainerProvider provider, Type type)
    {
        var list = type.GetExposedServicee();

        foreach (var item in list)
        {
            if (item.LifeTime == LifeTime.Singleton && item.AutoInitialize)
            {
                provider.Resolve(type); // 注册单例并初始化
            }
        }
    }

}
